package org.zjx.identify;

import lombok.Data;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;

@Data
public class PaneUtil {
    public int extendDistance = 5;
    public List<Color> colorList;
    private BufferedImage image;
    // 设置最小宽度的方法
    private int minWidth = 50;  // 最小宽度
    // 设置最小高度的方法
    private int minHeight = 10; // 最小高度
    // 设置验证点数量的方法
    private int verifyPoints = 2; // 验证点的数量（除了基准点外额外验证的点数）

    public PaneUtil(BufferedImage image, int extendDistance, List<Color> colorList) {
        this.image = image;
        this.extendDistance = extendDistance;
        this.colorList = colorList;
    }

    // 新增构造方法，可以指定最小宽度和高度
    public PaneUtil(BufferedImage image, int extendDistance, List<Color> colorList, int minWidth, int minHeight) {
        this.image = image;
        this.extendDistance = extendDistance;
        this.colorList = colorList;
        this.minWidth = minWidth;
        this.minHeight = minHeight;
    }

    // 新增构造方法，可以指定所有参数
    public PaneUtil(BufferedImage image, int extendDistance, List<Color> colorList, int minWidth, int minHeight, int verifyPoints) {
        this.image = image;
        this.extendDistance = extendDistance;
        this.colorList = colorList;
        this.minWidth = minWidth;
        this.minHeight = minHeight;
        this.verifyPoints = verifyPoints;
    }

    public List<Rectangle> detectRect() {
        List<Rectangle> rects = new ArrayList<>();
        int width = image.getWidth();
        int height = image.getHeight();

        // 一遍遍历收集所有角点
        List<Point> leftTopCorners = new ArrayList<>();
        List<Point> leftBottomCorners = new ArrayList<>();
        List<Point> rightTopCorners = new ArrayList<>();
        List<Point> rightBottomCorners = new ArrayList<>();

        for (int y = 0; y < height; y++) {
            for (int x = 0; x < width; x++) {
                // 检查左上角
                if (isLeftTopCorner(x, y)) {
                    leftTopCorners.add(new Point(x, y));
                }
                // 检查左下角
                if (isLeftBottomCorner(x, y)) {
                    leftBottomCorners.add(new Point(x, y));
                }
                // 检查右上角
                if (isRightTopCorner(x, y)) {
                    rightTopCorners.add(new Point(x, y));
                }
                // 检查右下角
                if (isRightBottomCorner(x, y)) {
                    rightBottomCorners.add(new Point(x, y));
                }
            }
        }

        // 组合匹配：左上角 + 右上角 + 左下角 + 右下角
        for (Point lt : leftTopCorners) {
            for (Point rt : rightTopCorners) {
                if (rt.y == lt.y && rt.x > lt.x) {
                    for (Point lb : leftBottomCorners) {
                        if (lb.x == lt.x && lb.y > lt.y) {
                            for (Point rb : rightBottomCorners) {
                                if (rb.x == rt.x && rb.y == lb.y) {
                                    int rectWidth = rb.x - lt.x + 1;
                                    int rectHeight = rb.y - lt.y + 1;

                                    // 检查是否满足最小宽度和高度条件
                                    if (rectWidth >= minWidth && rectHeight >= minHeight) {
                                        Rectangle rect = new Rectangle(
                                                lt.x, lt.y,
                                                rectWidth,
                                                rectHeight
                                        );
                                        rects.add(rect);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }

        return rects;
    }

    // 验证指定方向上的连续点
    private boolean verifyPointsInDirection(int startX, int startY, int deltaX, int deltaY) {
        for (int i = 0; i <= verifyPoints; i++) {
            int checkX = startX + deltaX * i;
            int checkY = startY + deltaY * i;

            // 检查边界
            if (checkX < 0 || checkX >= image.getWidth() || checkY < 0 || checkY >= image.getHeight()) {
                return false;
            }

            Color color = new Color(image.getRGB(checkX, checkY));
            if (!isColorMatch(color)) {
                return false;
            }
        }
        return true;
    }

    // 判断是否是左上角：下方和右方extendDistance处有边框颜色，并验证延续的点
    private boolean isLeftTopCorner(int x, int y) {
        // 验证下方连续点（向下方向）
        boolean bottomVerified = verifyPointsInDirection(x, y + extendDistance, 0, 1);
        // 验证右方连续点（向右方向）
        boolean rightVerified = verifyPointsInDirection(x + extendDistance, y, 1, 0);

        return bottomVerified && rightVerified;
    }

    // 判断是否是左下角：上方和右方extendDistance处有边框颜色，并验证延续的点
    private boolean isLeftBottomCorner(int x, int y) {
        // 验证上方连续点（向上方向）
        boolean topVerified = verifyPointsInDirection(x, y - extendDistance, 0, -1);
        // 验证右方连续点（向右方向）
        boolean rightVerified = verifyPointsInDirection(x + extendDistance, y, 1, 0);

        return topVerified && rightVerified;
    }

    // 判断是否是右上角：下方和左方extendDistance处有边框颜色，并验证延续的点
    private boolean isRightTopCorner(int x, int y) {
        // 验证下方连续点（向下方向）
        boolean bottomVerified = verifyPointsInDirection(x, y + extendDistance, 0, 1);
        // 验证左方连续点（向左方向）
        boolean leftVerified = verifyPointsInDirection(x - extendDistance, y, -1, 0);

        return bottomVerified && leftVerified;
    }

    // 判断是否是右下角：上方和左方extendDistance处有边框颜色，并验证延续的点
    private boolean isRightBottomCorner(int x, int y) {
        // 验证上方连续点（向上方向）
        boolean topVerified = verifyPointsInDirection(x, y - extendDistance, 0, -1);
        // 验证左方连续点（向左方向）
        boolean leftVerified = verifyPointsInDirection(x - extendDistance, y, -1, 0);

        return topVerified && leftVerified;
    }

    // 判断颜色是否匹配
    private boolean isColorMatch(Color pixelColor) {
        for (Color color : colorList) {
            if (color.equals(pixelColor)) {
                return true;
            }
        }
        return false;
    }

    // 同时设置最小宽度和高度的方法
    public void setMinSize(int minWidth, int minHeight) {
        this.minWidth = minWidth;
        this.minHeight = minHeight;
    }

}